/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Domain;

import java.util.List;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import objects.Message;
import objects.User;
import java.util.concurrent.Semaphore;
import objects.Frm;
import objects.Trd;

/**
 *
 * @author Tal Cohen
 */
public class DataManager {
    private static DataManager _dm;

   public static boolean isConnected = false;
    public static int FAILURE = 0;
    public static int SUCCESS = 1;

    private int _userType;       // 0 - defaultUser , 1 - manager
    private String _currUser;
    private String _currForum;
    private String _currThread;

    private Vector<User> _users;
    private boolean _userArrived;
    private Vector<User> _friends;
    private boolean _friendsArrived;
    private Vector<Frm> _forums;
    private Vector<Trd> _threads;
    private Vector<Message> _messages;
    private int _successOrFailure;
    private Vector<String> _notifications;

    private Semaphore _vectorUsersSem;
    private Semaphore _vectorForumsSem;
    private Semaphore _vectorFriendsSem;
    private Semaphore _successOrFailureSem;
    private Semaphore _vectorThreadsSem;
    private Semaphore _typeOfUserSem;
    private Semaphore _notificationSem;
    private final Object _notificationsLock;

//    private Controller _controller;

    private DataManager()
    {
        this._userType = 0;
        this._currUser = null;
        this._currForum = null;
        this._currThread= null;
        this._currUser="";
        this._users = null;
        this._userArrived = false;
        this._friends = null;
        this._friendsArrived = false;
        this._notifications = new Vector<String>();

        this._vectorUsersSem = new Semaphore(0);
        this._vectorForumsSem = new Semaphore(0);
        this._vectorFriendsSem = new Semaphore(0);
        this._successOrFailureSem = new Semaphore(0);
        this._vectorThreadsSem = new Semaphore(0);
        this._typeOfUserSem = new Semaphore(0);
        this._notificationSem = new Semaphore(0);
        this._notificationsLock = new Object();
    }

    public static DataManager getDataManager()
    {
            if(_dm == null)
                _dm = new DataManager();
            return _dm;
    }

    public synchronized String getCurrForum()
    {
        return _currForum;
    }

    public synchronized String  getCurrThread()
    {
        return _currThread;
    }

    public synchronized void setCurrForum(String _currForum)
    {
        this._currForum = _currForum;
    }

    public synchronized void setCurrThread(String _currThread) {
        this._currThread = _currThread;
    }

   public synchronized void setCurrUser(String user)
    {
        this._currUser = user;
    }

   public synchronized String getCurrUser() {
        return this._currUser;
    }


    //------------------------------------------------getting the User Vector------------------------------------------

    public void setVectorOfUsers(Vector<User> users) {
            this._users = users;
            this._vectorUsersSem.release();
    }

    public Vector<User> getVectorUser()
    {
        try {
            this._vectorUsersSem.acquire();
            if(DataManager.isConnected == false){
            	Thread.currentThread().stop();
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
        }
            return this._users;
    }

        //------------------------------------------------getting the friends Vector------------------------------------------

    public void setVerctorFriends(Vector<User> friends) {
            this._friends = friends;
            this._vectorFriendsSem.release();
    }

    public Vector<User> getVectorFriends()
    {
        try {
            this._vectorFriendsSem.acquire();
            if(DataManager.isConnected == false){
            	Thread.currentThread().stop();
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
        }
            return this._friends;
    }

        //------------------------------------------------getting the forums Vector------------------------------------------

    public void setVectorForums(Vector<Frm> forums) {
            this._forums = forums;
            this._vectorForumsSem.release();
    }

public Vector<Frm> getVectorForums()
    {
        try {
            this._vectorForumsSem.acquire();
            if(DataManager.isConnected == false){
            	Thread.currentThread().stop();
            }

        } catch (InterruptedException ex) {
            Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println(ex);
        }
        return this._forums;
    }

        //------------------------------------------------getting the Threads Vector------------------------------------------

    public void setVerctorThreads(Vector<Trd> threads) {
            this._threads = threads;
            this._vectorThreadsSem.release();
    }

    public Vector<Trd> getVectorThreads()
    {
        try {
            this._vectorThreadsSem.acquire();
              if(DataManager.isConnected == false){
            	Thread.currentThread().stop();
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
        }
            return this._threads;
    }

      //------------------------------------------------checking success------------------------------------------

    public void setSuccessOrFailure(int typeOfExit) {
            this._successOrFailure = typeOfExit;
            this._successOrFailureSem.release();
    }

    public int getSuccessOrFailure()    {
        try {
            this._successOrFailureSem.acquire();
             if(DataManager.isConnected == false){
            	Thread.currentThread().stop();
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
        }
            return this._successOrFailure;
    }

      //------------------------------------------------getting type of user------------------------------------------

    public void setTypeOfUser(int type) {
            this._userType = type;
            this._typeOfUserSem.release();
    }

    public int getTypeOfUser(){
        try {
            this._typeOfUserSem.acquire();
            if(DataManager.isConnected == false){
            	Thread.currentThread().stop();
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return this._userType;
    }

    public int getCurrTypeOfUser()
    {
        return this._userType;
    }

   //------------------------------------------------getting the next notification------------------------------------------

    public void addNotification(String notif) {
            synchronized (this._notificationsLock)
            {
                this._notifications.add(notif);
                this._notificationSem.release();
                //System.out.println("Was here 1!!!");
            }
    }

    public String getNotification(){

           // System.out.println("Was here 1.25!!!");
            String ans = null;
            //System.out.println("Was here 1.5!!!");

            try {
                this._notificationSem.acquire();
                if(DataManager.isConnected == false){
                    Thread.currentThread().stop();
                }
            } catch (InterruptedException ex) {
                Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
            }
           // System.out.println("Was here 2!!!");

            synchronized(this._notificationsLock)
            {
                ans = this._notifications.remove(0);
            }

            //System.out.println("Was here 3!!!");

            return ans;
    }

    public Vector<Message> getMessages() {
        return _messages;
    }

    public void setVectorMessages(Vector<Message> messages) {
       _messages = messages;
        this._successOrFailureSem.release();
    }

    public void releaseAllKeys(){
      _vectorUsersSem.release();
      _vectorForumsSem.release();
      _vectorFriendsSem.release();
      _successOrFailureSem.release();
      _vectorThreadsSem.release();
      _typeOfUserSem.release();
      _notificationSem.release();
    }

}
